<template>
    <div class="zc-box-search" v-if="props.searchOptions">
        <el-row :gutter="20">
            <el-col v-for="st in props.searchOptions.operations" :key="st.name" :span="4">
                <component
                        :is="st.component"
                        :name="st.name"
                        :multiple="st.multiple"
                        v-model="props.searchOptions.params[st.name]"
                        v-if="st.component"
                ></component>
                <el-input
                        v-else
                        :placeholder="st.text"
                        v-model="props.searchOptions.params[st.name]"
                        clearable
                />
            </el-col>
            <el-col :span="3">
                <el-button plain type="primary" @click="doQuery">确定</el-button>
                <el-button plain type="primary" @click="doRest">重置</el-button>
            </el-col>
        </el-row>
    </div>
    <Table
            :selection="options.selection"
            :loader="options.loader"
            :params="searchOptions?.params"
            :fixParams="list.fixParams"
            :operate="options.operate"
            ref="refPageList"
    >
        <template #toolbar v-if="create && create.api">
            <el-button plain type="primary" @click="doCreate">新增</el-button>
        </template>

        <template #columns>
            <el-table-column
                    :prop="item.name"
                    show-overflow-tooltip
                    :label="item.text ? item.text : item.label"
                    :width="item.width ? item.width : ''"
                    v-for="item in config.tableFields"
                    :formatter="item.format ? item.format : null"
                    :key="item.name"
            />
        </template>
    </Table>
    <DialogForm
            @submit="doSubmit"
            ref="dialogFormRef"
            :rules="rules"
            :fields="fields"
            :formOptions="formOptions"
            :detail="detail"
    >
        <template v-slot:formItem="forms">
            <el-row :gutter="20">
                <el-col v-for="field in config.formFields" :span="12">
                    <el-form-item
                            :label="field.label"
                            :prop="field.name"
                            :key="field.name"
                    >
                        <el-input
                                type="text"
                                v-model="forms.data[field.name]"
                                :placeholder="field.placeholder"
                                :show-word-limit="field.showWordLimit"
                                :maxlength="field.maxLength"
                                v-if="field.type === 'input' && field.showForm"
                        />
                        <el-input
                                type="textarea"
                                :autosize="{
            minRows: field.minRows ? field.minRows : 2,
            maxRows: field.maxRows ? field.maxRows : 4
          }"
                                v-model="forms.data[field.name]"
                                :placeholder="field.placeholder"
                                :maxlength="field.maxLength"
                                :show-word-limit="field.showWordLimit"
                                v-if="field.type === 'textarea' && field.showForm"
                        />

                        <el-switch v-model="forms.data[field.name]"
                                   :active-value="1"
                                   :inactive-value="0"
                                   v-if="field.type === 'switch'&& field.showForm">
                        </el-switch>

                        <component
                                :is="field.component"
                                :name="field.name"
                                :multiple="field.multiple"
                                v-model="forms.data[field.name]"
                                v-if="field.component"
                        ></component>
                        <span class="zc-description" v-if="field.description">{{ field.description }}</span>
                    </el-form-item>
                </el-col>
            </el-row>
        </template>
    </DialogForm>
</template>
<script setup type="ts">
import {onMounted, reactive, ref, nextTick} from "vue";
import Table from "@/components/core/table/index.vue";
import DialogForm from '../forms/index.vue'
import {ElMessage, ElMessageBox} from "element-plus";
import router from "@/router";

const dialogFormRef = ref();
const refPageList = ref();
const dialog = reactive({show: false, title: '', id: null})
const config = reactive({formFields: [], tableFields: []})

const props = defineProps({
    create: {
        type: Object
    },
    delete: {
        type: Object
    },
    update: {
        type: Object
    },
    detail: {
        type: Object
    },
    list: {
        type: Object
    },
    fields: {
        type: Array
    },
    rules: {
        type: Object
    },
    formOptions: {
        type: Object
    },
    // 自定义操作配置
    operateOptions: {
        type: Object
    },
    searchOptions: {
        type: Object
    },
    // 扩展按钮操作
    buttonOptions: {
        type: Object
    }
});
// 查询条件
const doQuery = () => {
    refPageList.value.reloadData(props.searchOptions?.params);
}

const doRest = () => {
    props.searchOptions.params = {};
    nextTick(() => {
        refPageList.value.reloadData(props.searchOptions.params);
    });
}

const loadData = () => {
    refPageList.value.doLoadData(props.searchOptions?.params);
}

const doDetail = (row) => {
    router.push({name: props.detail.router, params: {id: row.id}})
}

const doCreate = () => {
    dialog.show = true;
    dialog.id = null;
    dialog.title = props.create.title;
    dialogFormRef.value.doDialogOpen(dialog);
}
const doUpdate = (row) => {
    dialog.show = true;
    dialog.id = row.id;
    dialog.title = props.update.title;
    dialogFormRef.value.doDialogOpen(dialog);
}

const doSubmit = (forms) => {
    // 提交前处理
    if (props.formOptions && props.formOptions.onBeforeSubmit) {
        props.formOptions.onBeforeSubmit(forms);
    }
    if (forms.id) {
        props.update.api(forms)
            .then(res => {
                if (res.data) {
                    // 提交后处理
                    if (props.formOptions && props.formOptions.onAfterSubmit) {
                        props.formOptions.onAfterSubmit(res.data);
                    } else {
                        ElMessage.success("更新成功");
                    }
                    loadData();
                }
            })
            .catch((e) => {
                ElMessage.error("更新失败:" + e);
            })

    } else {
        props.create.api(forms)
            .then(res => {
                if (res.data) {
                    // 提交后处理
                    if (props.formOptions && props.formOptions.onAfterSubmit) {
                        props.formOptions.onAfterSubmit(res.data);
                    } else {
                        ElMessage.success("新增成功");
                    }
                    loadData();
                }
            })
            .catch((e) => {
                ElMessage.error("新增失败:" + e);
            })
    }
}

const doDelete = (row) => {
    if (props.delete && props.delete.api) {
        const title = props.delete.titile || "确定删除此数据？";
        ElMessageBox.confirm(title, "确定", {}).then(() => {
            props.delete.api({id: row.id})
                .then((res) => {
                    if (res.data) {
                        ElMessage.success("删除成功");
                        loadData();
                    }
                });
        });
    }
}


const options = reactive({
    selection: true,
    operate: {
        display: true,
        width: '150px',
        buttons: [
            {
                label: '编辑',
                size: 'small',
                display: props.update || false,
                doClick: doUpdate
            },
            {
                label: '删除',
                size: 'small',
                display: props.delete || false,
                disabled: props.delete?.disabled,
                doClick: doDelete
            },
            {
                label: '详情',
                size: 'small',
                display: props?.detail?.router || false,
                doClick: doDetail
            }
        ]
    },
    loader: (params) => {
        // 排序规则
        params.sort = params.sort ? params.sort : props.list.sort;
        return props.list.api(params);
    }
})


onMounted(() => {
    if (props.list.autoLoad !== false) {
        loadData();
    }
    // 处理表单展示的字段
    config.formFields = props.fields.filter(e => e.showForm);
    config.tableFields = props.fields.filter(e => e.showList);
    if (props.operateOptions) {
        options.selection = props.operateOptions.selection || options.selection;
        options.operate = props.operateOptions.operate || options.operate;
    }
    if (props.buttonOptions) {
        props.buttonOptions.forEach(b => {
            options.operate.buttons.push(b);
        })
    }
});

const exposed = {
    loadData
};
defineExpose(exposed);
</script>
